#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "Relationship.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class Property;
class Type;

/// <summary>
/// Association
/// A link is a tuple of values that refer to typed objects.  An Association
/// classifies a set of links, each of which is an instance of the Association. 
/// Each value in the link refers to an instance of the type of the corresponding
/// end of the Association.
/// 
/// </summary>
class UMLMODEL_EXPORT Association : public Relationship {

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Methods
public: // Properties
    /// <summary>
    /// endTypes getter
    /// The Classifiers that are used as types of the ends of the Association.
    /// </summary>
    vector<shared_ptr<Type>>& endTypes();

    /// <summary>
    /// isDerived getter
    /// Specifies whether the Association is derived from other model elements such as
    /// other Associations.
    /// </summary>
    bool isDerived() const;

    /// <summary>
    /// isDerived setter
    /// Specifies whether the Association is derived from other model elements such as
    /// other Associations.
    /// </summary>
    void setIsDerived(bool value);

    /// <summary>
    /// memberEnds getter
    /// Each end represents participation of instances of the Classifier connected to
    /// the end in links of the Association.
    /// </summary>
    vector<shared_ptr<Property>>& memberEnds();

    /// <summary>
    /// navigableOwnedEnds getter
    /// The navigable ends that are owned by the Association itself.
    /// </summary>
    vector<shared_ptr<Property>>& navigableOwnedEnds();

    /// <summary>
    /// ownedEnds getter
    /// The ends that are owned by the Association itself.
    /// </summary>
    vector<shared_ptr<Property>>& ownedEnds();

private: // Fields
    /// <summary>
    /// endTypes
    /// The Classifiers that are used as types of the ends of the Association.
    /// </summary>
    vector<shared_ptr<Type>> endTypes_;

    /// <summary>
    /// isDerived
    /// Specifies whether the Association is derived from other model elements such as
    /// other Associations.
    /// </summary>
    const static bool isDerived_default_;
    bool isDerived_= isDerived_default_;

    /// <summary>
    /// memberEnds
    /// Each end represents participation of instances of the Classifier connected to
    /// the end in links of the Association.
    /// </summary>
    vector<shared_ptr<Property>> memberEnds_;

    /// <summary>
    /// navigableOwnedEnds
    /// The navigable ends that are owned by the Association itself.
    /// </summary>
    vector<shared_ptr<Property>> navigableOwnedEnds_;

    /// <summary>
    /// ownedEnds
    /// The ends that are owned by the Association itself.
    /// </summary>
    vector<shared_ptr<Property>> ownedEnds_;

};

} // namespace uml
